using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Banshee.Base;
using Banshee.MediaEngine;
using u4 = Un4seen.Bass;
using MediaPortal.Player; //Cornel I dont know if you guys use aliases but im so not
                         // gonna type Un4seen.Bass.Bass.Class all the time :P
public static class PluginModuleEntry
{
    public static Type[] GetTypes()
    {
        return new Type[] {
            typeof(Banshee.MediaEngine.BassEngine.BassPlayerEngine)
        };
    }
}
namespace Banshee.MediaEngine.BassEngine
{

    public class BassPlayerEngine : PlayerEngine
    {
        BassAudioEngine player = null;
        private string plugin_path = Banshee.Base.ConfigureDefines.InstallDir;
        public BassPlayerEngine()
        {
            player = new BassAudioEngine();
            player.InitBass();
            player.PlaybackStateChanged += new BassAudioEngine.PlaybackStateChangedDelegate(player_PlaybackStateChanged);
            player.PlaybackProgress += new BassAudioEngine.PlaybackProgressHandler(player_PlaybackProgress);
            player.PlaybackStop += new BassAudioEngine.PlaybackStopHandler(player_PlaybackStop);
        }

        void player_PlaybackStop(object sender)
        {
            OnEventChanged(PlayerEngineEvent.EndOfStream);
        }

        void player_PlaybackProgress(object sender, float duration, float curPosition)
        {
            
            this.Position = Convert.ToUInt32(curPosition);
            //Console.WriteLine("{0} {1} {2}", duration, curPosition,this.Position);
            OnEventChanged(PlayerEngineEvent.Iterate);
        }

        void player_PlaybackStateChanged(object sender, BassAudioEngine.PlayState oldState, BassAudioEngine.PlayState newState)
        {
            switch (newState)
            {
                case BassAudioEngine.PlayState.Init:
                    break;
                case BassAudioEngine.PlayState.Playing:
                    OnStateChanged(PlayerEngineState.Playing);
                    break;
                case BassAudioEngine.PlayState.Paused:
                    OnStateChanged(PlayerEngineState.Paused);
                    break;
                case BassAudioEngine.PlayState.Ended:
                    OnEventChanged(PlayerEngineEvent.EndOfStream);
                    break;
            }
        }
        Hashtable loadedPlugIns;
        void LoadPlugins()
        {
            loadedPlugIns = u4.Bass.BASS_PluginLoadDirectory(plugin_path);
        }
        protected override void OpenUri(SafeUri uri)
        {
            player.Play(uri.AbsolutePath);
            OnEventChanged(PlayerEngineEvent.StartOfStream);
        }

        public override void Pause()
        {
            player.Pause();
        }
        
        public override ushort Volume
        {
            get
            {
                return Convert.ToUInt16(player.Volume);
            }
            set
            {
                player.Volume =Convert.ToInt32(value);
            }
        }

        public override uint Position
        {
            get
            {
                return Convert.ToUInt16(player.CurrentPosition);
            }
            set
            {
                
            }
        }

        public override uint Length
        {
            get { return 0; }
        }
        private static string[] source_capabilities = { "file", "cdda" };
        public override System.Collections.IEnumerable SourceCapabilities
        {
            get { return source_capabilities; }
        }
        string[] explicitDecoderCapabilities;
        public override System.Collections.IEnumerable ExplicitDecoderCapabilities
        {
            get {
                if (explicitDecoderCapabilities == null)
                {
                    string plugs = string.Empty;

                    for (int i = 0; i < player.LoadedPluginHandles.Count; i++)
                    {

                        u4.BASS_PLUGININFO pluginInfo = u4.Bass.BASS_PluginGetInfo(player.LoadedPluginHandles[i]);
                        foreach (u4.BASS_PLUGINFORM formats in pluginInfo.formats)
                        {
                            plugs += formats + ",";
                        }

                    }
                    plugs.Remove(plugs.Length - 1, 1);
                    string[] result = plugs.Split(',');
                    explicitDecoderCapabilities = result;
                }
                return explicitDecoderCapabilities;
            }
        }

        public override string Id
        {
            get { return "bass.net"; }
        }

        public override string Name
        {
            get { return "Bass.Net"; }
        }
    }
}
